package com.foreveross.project.usercenterserver.oauth2.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreveross.project.usercenterserver.common.constant.GlobalConstant;
import com.foreveross.project.usercenterserver.common.utils.CodeUtils;
import com.foreveross.project.usercenterserver.common.utils.ContextUtil;
import com.foreveross.project.usercenterserver.common.utils.RedisUtil;
import com.foreveross.project.usercenterserver.exception.CustomException;
import com.foreveross.project.usercenterserver.oauth2.domain.UcTenant;
import com.foreveross.project.usercenterserver.oauth2.dto.TenantDto;
import com.foreveross.project.usercenterserver.oauth2.enums.DelFlagEnum;
import com.foreveross.project.usercenterserver.oauth2.mapper.UcTenantMapper;
import com.foreveross.project.usercenterserver.oauth2.service.IUcTenantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yz
 * @since 2019-07-19
 */
@Service
public class UcTenantServiceImpl extends ServiceImpl<UcTenantMapper, UcTenant> implements IUcTenantService {

    @Override
    public UcTenant findByClientId(String clientId) {
        return baseMapper.findByClientId(clientId);
    }


    @Autowired
    PasswordEncoder passwordEncoder;

    /**
     * 创建租户
     *
     * @param tenantDto
     * @return
     */
    @Override
    public UcTenant createTenant(TenantDto tenantDto) {
        this.validityData(tenantDto);
        UcTenant ucTenant = new UcTenant();
        //设置授权类型
        ucTenant.setAuthorizedGrantTypes(tenantDto.getAuthorizedGrantTypes());
        ucTenant.setDelFlag(DelFlagEnum.NORMAL.getDelFlag());
        ucTenant.setClientId(tenantDto.getClientId());
        ucTenant.setDescription(tenantDto.getDescription());
        ucTenant.setCreateAt(new Date());
        ucTenant.setCreateBy(ContextUtil.getCurrentUserId());
        ucTenant.setAutoApprove(GlobalConstant.TENANT_AUTO_APPROVE);
        ucTenant.setWebServerRedirectUri(tenantDto.getWebServerRedirectUri());
        ucTenant.setClientSecret(passwordEncoder.encode(tenantDto.getClientecret()));
        ucTenant.setScope("");
        ucTenant.setAuthorities(GlobalConstant.TENANT_AUTHORITIES);
        ucTenant.setRefreshTokenValidity(GlobalConstant.TENANT_REFRESH_TOKEN_VALIDITY);
        ucTenant.setAccessTokenValidity(GlobalConstant.TENANT_TOKEN_VALIDITY);
        ucTenant.setTenantName(tenantDto.getTenantName());
        ucTenant.setTenantFkId(CodeUtils.getUUID());
        int insertId = baseMapper.insert(ucTenant);
        ucTenant.setId(insertId);
        return ucTenant;
    }

    @Override
    public UcTenant updateTenant(TenantDto tenantDto) {
        this.validityData(tenantDto);
        // UcTenant ucTenant = new UcTenant();
        QueryWrapper<UcTenant> wrapper = new QueryWrapper<>();
        wrapper.eq("tenant_fk_id", tenantDto.getTenantFkId());
        UcTenant tenant = baseMapper.selectOne(wrapper);
        BeanUtil.copyProperties(tenantDto, tenant);
        System.out.println(tenant);
        tenant.setUpdateAt(new Date());
        tenant.setUpdateBy(ContextUtil.getCurrentUserId());
        baseMapper.updateById(tenant);
        return tenant;
    }

    /**
     * 删除租户
     *
     * @param tenantFkId
     */
    @Override
    public void deleteTenant(String tenantFkId) {
        QueryWrapper<UcTenant> wrapper = new QueryWrapper<>();
        wrapper.eq("tenant_fk_id", tenantFkId);
        UcTenant tenant = baseMapper.selectOne(wrapper);
        //TODO 是否需要检查操作权限？当前操作人是否该记录的创建者？
        if (ObjectUtil.isNull(tenant)) {
            throw new CustomException(GlobalConstant.ERROR_TENANT_NON_EXISTENT_MSG);
        }
        tenant.setDelFlag(DelFlagEnum.ISDEL.getDelFlag());
        tenant.setUpdateAt(new Date());
        tenant.setUpdateBy(ContextUtil.getCurrentUserId());
        //TODO 删除租户的时候设置租户下的各种资源不可用？？？
        RedisUtil.delete(tenant.getClientId());
        baseMapper.updateById(tenant);
    }


    @Override
    public IPage<TenantDto> queryForPage(Page<TenantDto> page, Map<String, Object> params) {
        return baseMapper.queryForPage(page,params);
    }

    @Override
    public UcTenant findTenant(String tenantFkId) {
        QueryWrapper<UcTenant> wrapper = new QueryWrapper<>();
        wrapper.eq("tenant_fk_id", tenantFkId);
        UcTenant tenant = baseMapper.selectOne(wrapper);
        return tenant;
    }

    /**
     * 验证信息
     *
     * @param tenantDto
     */
    private void validityData(TenantDto tenantDto) {
        /**
         * 修改时检查该记录是否操作人
         */
        UcTenant tenant = baseMapper.findByClientId(tenantDto.getClientId());
        if (StrUtil.isNotEmpty(tenantDto.getTenantFkId())) {
            //修改
            QueryWrapper<UcTenant> wrapper = new QueryWrapper<>();
            wrapper.eq("tenant_fk_id", tenantDto.getTenantFkId());
            UcTenant existsTenant = baseMapper.selectOne(wrapper);
            if (ObjectUtil.isNull(existsTenant)) {
                throw new CustomException(GlobalConstant.ERROR_TENANT_NON_EXISTENT_MSG);
            }
            if (!StrUtil.equals(existsTenant.getCreateBy(), ContextUtil.getCurrentUserId())) {
                throw new CustomException(GlobalConstant.ERROR_TENANT_NON_CREATOR_MSG);
            }
            //检查是否存在相同的clientId
            if (!StrUtil.equals(tenant.getTenantFkId(), existsTenant.getTenantFkId())) {
                throw new CustomException(GlobalConstant.ERROR_TENANT_REPEAT_MSG);
            }

        } else {
            //新增
            if (ObjectUtil.isNotNull(tenant)) {
                throw new CustomException(GlobalConstant.ERROR_TENANT_REPEAT_MSG);
            }
        }
    }
}
